#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
#include <assert.h>
using namespace std;

class Date
{
public:
    // Date 类包含三个整型成员变量，这些变量都是值类型，所以它们的拷贝构造是浅拷贝，即直接复制值。
    Date(int year = 1900, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
    }

    Date(const Date &dd)
    {
        _year = dd._year;
        _month = dd._month;
        _day = dd._day;
    }

    void Print()
    {
        cout << _year << "/" << _month << "/" << _day << endl;
    }

private:
    int _year;
    int _month;
    int _day;
};

// Stack 类包含动态分配的内存（通过malloc分配），因此它的拷贝构造需要实现深拷贝，以避免多个栈对象共享同一块内存。
// 析构函数会销毁那片空间，但是另一个还是指向那里，这样会导致同一块空间被释放两次

class Stack
{
public:
    Stack(size_t capacity = 3)
    {
        cout << "Stack(size_t capacity = 3)" << endl;

        _a = (int *)malloc(sizeof(int) * capacity);
        if (nullptr == _a)
        {
            perror("malloc申请空间失败!!!");
        }
        // 这里首先为新的栈对象分配内存，然后使用memcpy复制
        // 现有栈对象的数据。最后，复制栈顶指针和容量。
        _capacity = capacity;
        _top = 0;
    }

    // Stack st2(st1);
    Stack(const Stack &stt)
    {
        cout << "	Stack(Stack& stt)" << endl;
        // 深拷贝
        _a = (int *)malloc(sizeof(int) * stt._capacity);
        if (_a == nullptr)
        {
            perror("malloc fail");
            exit(-1);
        }
        memcpy(_a, stt._a, sizeof(int) * stt._top);
        _top = stt._top;
        _capacity = stt._capacity;
    }

    // 10:40继续
    ~Stack()
    {
        cout << "~Stack()" << endl;

        free(_a);
        _capacity = _top = 0;
        _a = nullptr;
    }

private:
    int *_a;
    int _capacity;
    int _top;
};

// MyQueue 类使用了两个Stack对象作为其成员。由于Stack类已经实现了深拷贝，
// 所以MyQueue类的默认拷贝构造（由编译器自动生成）将正确地执行深拷贝。这意味着当你复制一个MyQueue对象时，
// 它的两个栈成员也会被正确地复制。
class MyQueue
{
    Stack _pushst;
    Stack _popst;
    int _size = 0;
};

// 浅拷贝/值拷贝
void func1(Date d)
{
    d.Print();
}

// 对于栈类不行，
void func2(Stack st)
{
    //...
}

// void func3(Tree t)
//{
//
// }

int main()
{
    // Date 和 MyQueue 默认生成拷贝就可以用
    // 1、内置类型成员完成值拷贝
    // 2、自定义类型成员调用这个成员的拷贝构造
    // Stack需要自己写拷贝构造，完成深拷贝。
    // 顺序表、链表、二叉树等等的类，都需要深拷贝
    // 自己开空间的一般都需要

    Date d1(2023, 10, 22); // 拷贝构造两个使用场景
    func1(d1);             // 1.传参的时候
    // Date d2(d1);	//2.初始化构造的时候	这样子其实也是拷贝构造，构造一个日期类的d2，用d1来初始化

    Stack st1;
    func2(st1);

    // Stack st2(st1);

    // MyQueue q1;
    // MyQueue q2(q1);

    return 0;
}

// Stack& func2()
//{
//	static Stack st;
//
//	return st;
// }
//
// int main()
//{
//
//	func2();
//
//	return 0;
// }

// 12.1  +9

////////////////////////////////////////////////////////////////////////////
// 运算符重载
// class Date
//{
// public:
//	Date(int year = 1, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//
//	//Date(const Date& dd)
//	//{
//	//	_year = dd._year;
//	//	_month = dd._month;
//	//	_day = dd._day;
//	//}
//
//	void Print()
//	{
//		cout << _year << "/" << _month << "/" << _day << endl;
//	}
//
////private:
//	int _year;
//	int _month;
//	int _day;
//};
//
////bool Greater(Date x, Date y)
////bool Compare1(Date x, Date y)
// bool operator>(const Date& x, const Date& y)
//{
//	if (x._year > y._year)
//	{
//		return true;
//	}
//	else if (x._year == y._year && x._month > y._month)
//	{
//		return true;
//	}
//	else if (x._year == y._year && x._month == y._month && x._day > y._day)
//	{
//		return true;
//	}
//
//	return false;
// }
//
////bool Equal(Date x, Date y)
////bool Compare2(Date x, Date y)
////bool xiangdeng(Date x, Date y)
// bool operator==(const Date& x, const Date& y)
//{
//	return x._year == y._year
//		&& x._month == y._month
//		&& x._day == y._day;
// }
//
// int main()
//{
//	Date d1;
//	Date d2(2023, 10, 22);
//
//	//d1 == d2;
//	//d1 > d2;
//	/*cout << Compare1(d1, d2) << endl;
//	cout << xiangdeng(d1, d2) << endl;*/
//
//	// 运算符重载 与函数重载
//	// 他们之间没有关联
//	// 运算符重载：自定义类型可以直接使用运算符
//	// 函数重载：可以允许参数不同的同名函数，
//	cout << operator>(d1, d2) << endl; //记得带括号，因为有优先级
//	cout << operator==(d1, d2) << endl;
//	/*cout << (d1 > d2) << endl;
//	cout << (d1 == d2) << endl;*/
//	// 11:40 继续
//
//
//	//我写成这样，系统就会调用operator>(d1, d2)
//	bool ret1 = d1 > d2;  // operator>(d1, d2);
//	bool ret2 = d1 == d2; // operator==(d1, d2);
//
//	// 内置类型对象可以直接用各种运算符，内置类型都是简单类型
//	// 语言自己定义，编译直接转换成指令
//	// 自定义类型呢？不支持
//	/*int x = 1, y = 2;   //内置类型，直接转换成指令
//	bool ret1 = x > y;	  //如果是自定义类型，就看写没写自定义的函数
//	bool ret2 = x == y;*/
//
//	return 0;
// }

/////////////////////////////////////////////////////////////////////////////

// class Date
//{
// public:
//	Date(int year = 1, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//  //都是私有的
//	}
//
//	void Print()
//	{
//		cout << _year << "/" << _month << "/" << _day << endl;
//	}
//
//	//int GetYear();
//
//	bool operator==(const Date& y)
//	{
//		return _year == y._year
//			&& _month == y._month
//			&& _day == y._day;
//	}//类里面对象的访问不受限制
//
//	bool operator>(const Date& y)
//	{
//		if (_year > y._year)
//		{
//			return true;
//		}
//		else if (_year == y._year && _month > y._month)
//		{
//			return true;
//		}
//		else if (_year == y._year && _month == y._month && _day > y._day)
//		{
//			return true;
//		}
//
//		return false;
//	}
//
//	// d1 - d2
//	int operator-(const Date& d)
//	{
//		// ...
//		return 0;
//	}
//
//	int GetMonthDay(int year, int month)
//	{
//		assert(year >= 1 && month >= 1 && month <= 12);
//
//		int monthArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30,31 };
//
//		if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
//			return 29;//把判断二月写到前面，如果不满足二月，后面的就不执行了，省事。
//
//		return monthArray[month];
//	}
//
//	// d1 += 100
//	Date& operator+=(int day)
//	{
//		_day += day;
//		while (_day > GetMonthDay(_year, _month))
//		{
//			_day -= GetMonthDay(_year, _month);
//
//			++_month;
//
//			if (_month == 13)
//			{
//				_year++;
//				_month = 1;
//			}
//		}
//
//		return *this;// *this是d1， 返回d1
//  //传值返回也可以，但引用返回更好。
//	//*this
//	}
//
//	// //d1 + 50
//	////不用引用返回的
//	//Date operator+(int day)
//	//{
//	//	Date tmp(*this);//拷贝一份d1，作为tmp。不会影响d1
//
//	//	tmp._day += day;
//	//	while (tmp._day > GetMonthDay(tmp._year, tmp._month))
//	//	{
//	//		tmp._day -= GetMonthDay(tmp._year, tmp._month);
//
//	//		++tmp._month;
//
//	//		if (tmp._month == 13)
//	//		{
//	//			tmp._year++;
//	//			tmp._month = 1;
//	//		}
//	//	}
//
//	//	return tmp;
//	//}
//
//	Date operator+(int day)
//	{
//		Date tmp(*this);
//		tmp += day;
//
//		return tmp;
//	}
//
// private:
//	int _year;
//	int _month;
//	int _day;
// };
//
// int main()
//{
//	Date d1;
//	Date d2(2023, 10, 22);
//
//	bool ret1 = d1 > d2;  // d1.operator>(d2) -> d1.operator>(&d1, d2)
//	bool ret2 = d1 == d2; // d1.operator==(d2) -> d1.operator==(&d1, d2)
//
//
//	// d1.operator>(d2);
//
//	// 一个重载哪些运算符呢？主要这个运算符有没有意义
//	// 有意义就可以实现，没有意义就不要实现
//	//d1 + d2;
//	d1 - d2;
//	//d1 * d2;  //日期乘日期没意义
//	//d1 / d2;
//
//	d2 += 50;
//	d2.Print();
//
//	Date ret3 = d1 + 50;
//	d1.Print();
//	ret3.Print();
//
//	int i = 0, j = 0;
//	//i += 50;
//	int ret = j += i += 50;
//
//
//	return 0;
// }

//             简单是使用一下
// class Date
//{
// public:
//	void Init(int year)
//	{
//		mYear = year;
//	}
//	void PrintYear();
// private:
//	int mYear;
//};
// void Date::PrintYear()
//{
//	cout << "Year: " << mYear << endl;
//}
//
//
// int main()
//{
//	Date myDate;
//	myDate.Init(2023);
//	myDate.PrintYear();
//	cin.get();
//	return 0;
//}

// #include <iostream>
// using namespace std;
//
// class MemberVariablesClass {
// private:
//     char a; // 1 byte
//     int b;  // 4 bytes (通常)
//     char c; // 1 byte，但可能由于内存对齐而占用更多空间
// };
//
// int main() {
//     cout << "Size of MemberVariablesClass: " << sizeof(MemberVariablesClass) << " bytes" << endl;
//     return 0;
// }